package karaoke.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import karaoke.excepcion.DAOExcepcion;
import karaoke.modelo.Producto;
import karaoke.modelo.TipoProducto;
import karaoke.util.ConexionBD;

public class ProductoDAO extends BaseDAO {

	public Collection<Producto> buscarPorNombreCodigo(String nombreCodigo, int idlocal)
			throws DAOExcepcion {
		String query = "select * from producto where idlocal like ? and elog=0 and (nombre like ? or idproducto like ?)";
		Collection<Producto> lista = new ArrayList<Producto>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, (idlocal==0?"%":""+idlocal));
			stmt.setString(2, "%" + nombreCodigo + "%");
			stmt.setString(3, "%" + nombreCodigo + "%");
			rs = stmt.executeQuery();
			while (rs.next()) {
				Producto po = new Producto();
				po.setIdproducto(rs.getInt("idproducto"));
				po.setNombre(rs.getString("nombre"));
				po.setPrecio(rs.getDouble("precio"));
				po.setDisponible(rs.getInt("disponible")==1?true:false);
				
				TipoProductoDAO tpdao = new TipoProductoDAO();
				TipoProducto tp = tpdao.obtener(rs.getInt("idtipoproducto"));
				po.setIdtipoproducto(tp);
				lista.add(po);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return lista;
	}
	
	public Producto insertar(Producto po) throws DAOExcepcion {
		String query = "insert into producto(nombre, precio, elog, disponible, idtipoproducto, idlocal) values (?, ?, 0, ?, ?, ?)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, po.getNombre());
			stmt.setDouble(2, po.getPrecio());
			stmt.setInt(3, po.isDisponible()?1:0);
			stmt.setInt(4, po.getIdtipoproducto().getIdtipoproducto());
			stmt.setInt(5, po.getLocal().getIdlocal());
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}
			// Obtener el ultimo id
			int id = 0;
			query = "select last_insert_id()";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt(1);
			}
			po.setIdproducto(id);

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return po;
	}

	public Producto obtener(int idProducto) throws DAOExcepcion {
		Producto po = new Producto();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "select * from producto where idproducto=? and elog=0";
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idProducto);
			rs = stmt.executeQuery();
			if (rs.next()) {
				po.setIdproducto(rs.getInt("idproducto"));
				po.setNombre(rs.getString("nombre"));
				po.setPrecio(rs.getDouble("precio"));
				po.setElog(rs.getInt("elog")==1?true:false);
				po.setDisponible(rs.getInt("disponible")==1?true:false);
				
				TipoProductoDAO tpdao = new TipoProductoDAO();
				TipoProducto tpo = tpdao.obtener(rs.getInt("idtipoproducto"));
				po.setIdtipoproducto(tpo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return po;
	}

	public void eliminar(int idProducto) throws DAOExcepcion {
		String query = "update producto set elog=1 where idproducto=?";
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idProducto);
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo eliminar");
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}

	public Producto actualizar(Producto po) throws DAOExcepcion {
		String query = "update producto set nombre=?,precio=?,disponible=?,idtipoproducto=? where idproducto=?";
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = ConexionBD.obtenerConexion();
			con.setAutoCommit(false);
			stmt = con.prepareStatement(query);
			stmt.setString(1, po.getNombre());
			stmt.setDouble(2, po.getPrecio());
			stmt.setInt(3, po.isDisponible()?1:0);
			stmt.setInt(4, ((TipoProducto)po.getIdtipoproducto()).getIdtipoproducto());
			stmt.setInt(5, po.getIdproducto());
			int i = stmt.executeUpdate();
			if (i != 1) {
				con.rollback();
				throw new SQLException("No se pudo actualizar");
			}
			con.commit();
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return po;
	}

	public Collection<Producto> listar() throws DAOExcepcion {
		Collection<Producto> c = new ArrayList<Producto>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select * from producto where elog=0 order by nombre";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Producto po = new Producto();
				po.setIdproducto(rs.getInt("idproducto"));
				po.setNombre(rs.getString("nombre"));
				po.setPrecio(rs.getDouble("precio"));
				po.setDisponible(rs.getInt("disponible")==1?true:false);
				
				TipoProductoDAO tpdao = new TipoProductoDAO();
				TipoProducto tp = tpdao.obtener(rs.getInt("idtipoproducto"));
				po.setIdtipoproducto(tp);
				c.add(po);
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return c;
	}
	
	public Collection<Producto> listarByLocal(int idlocal) throws DAOExcepcion {
		Collection<Producto> c = new ArrayList<Producto>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select * from producto where elog=0 and idlocal=? order by nombre";
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idlocal);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Producto po = new Producto();
				po.setIdproducto(rs.getInt("idproducto"));
				po.setNombre(rs.getString("nombre"));
				po.setPrecio(rs.getDouble("precio"));
				po.setDisponible(rs.getInt("disponible")==1?true:false);
				
				TipoProductoDAO tpdao = new TipoProductoDAO();
				TipoProducto tp = tpdao.obtener(rs.getInt("idtipoproducto"));
				po.setIdtipoproducto(tp);
				
				c.add(po);
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return c;
	}
}
